/*
 * @Description: 
 * @Author: HuRrongChao
 * @Date: 2025-01-16 13:34:44
 * @LastEditors: HuRrongChao
 * @LastEditTime: 2025-01-23 15:44:53
 */

import { callHook, warning } from "../utils"

export class Barrage {
  constructor(opts) {
    Object.assign(this, opts)
    this.node = null
    this.show = true // 是否出现
    this.time = opts.time || 0 // 出现时间
    this.video = opts.video // 视频
    this.x = 0 // 位置
    this.speed = opts.speed || 1 // 速度
    this.hooks = opts.hooks
    this.container = opts.container
    this.direction = opts.direction || 'right'
    this.render = opts.render || this.defaultRender
    this.create()
  }

  // API
  getHeight() {
    return (this.node && this.node.clientHeight) || 0
  }

  // API
  getWidth() {
    return (this.node && this.node.clientWidth) || 0
  }

  // API
  getShowTime() {
    return this.time
  }

  // 弹幕加入到容器
  append() {
    warning(this.container, 'Need container element.')
    if (!this.node) return
    this.container.appendChild(this.node)
    callHook(this.hooks, 'append', [this, this.node])
  }

  // 弹幕移出容器
  remove() {
    warning(this.container, 'Need container element.')
    if (!this.node) return
    this.container.removeChild(this.node)
    callHook(this.hooks, 'remove', [this, this.node])
  }

  // 默认弹幕弹幕样式
  defaultRender() {
    const isNegative = this.direction === 'left' ? 1 : -1
    const node = document.createElement('div')
    node.innerText = this.value
    node.style.color = this.color
    node.style.fontSize = this.fontSize + 'px'
    node.style[this.direction] = - this.getWidth() + 'px'
    node.style.position = 'absolute'
    node.style.display = 'inline-block'

    const sheet = document.styleSheets[0]
    const keyframes = `@keyframes move { 0% { transform: translateX(0); } 100% { transform: translateX(${(this.video.clientWidth + this.getWidth()) * isNegative}px); } }`
    sheet.insertRule(keyframes, sheet.cssRules.length)
    node.style.animation = `move 1s linear forwards paused`

    return node
  }

  create() {
    this.node = this.render(this)
    callHook(this.hooks, 'create', [this, this.node])
  }

  // 销毁当前节点
  destroy() {
    this.show = false

    callHook(this.hooks, 'destroy', [this, this.node])
    this.node = null
  }
}